module BrianTheCoder
  module Plugins
    module SweetVersioning
      def self.included(mod)
        mod.extend(ClassMethods)
      end
  
      module ClassMethods
    
        mattr_accessor :versioning_options
    
        def sweet_versioning(*fields)
      
          return if self.included_modules.include?(Versioning::SingletonMethods)
      
          class_inheritable_accessor :versioning_options
      
          options = fields.find{ |f| f.class == Hash } || {}
      
      
          self.versioning_options = {
             :versioned_fields => fields.select{ |f| f.class == String || f.class == Symbol},
             :version_count_column => :version
          }.merge(options)
      
          has_many :versions, :as => :versionable
      
          after_save :update_version_on_change
      
      
          include Versioning::InstanceMethods
          class_eval do
            extend Versioning::SingletonMethods
          end
      
        end
      end
  
      module SingletonMethods
    
        def find_version(id, number)
          Version.find(:first, :conditions => ['versionable_id = ? AND position = ?',id,number])
        end
    
      end
  
      module InstanceMethods
    
        def revert_to(number)
          version = versions.find_by_position(number)
          unless version.nil?
            clone = self.class.new(self.attributes.merge(YAML.load(version.data)))
          end
        end
    
        def revert_to!(number)
          version = versions.find_by_position(number)
          unless version.nil?
            update_attributes(YAML.load(version.data))
          end
        end
    
        protected
    
          def update_version_on_change
            data = {}
            versioning_options[:versioned_fields].each{|f| data[f] = self[f]}
            if versions.empty? || versions.last.data != data.to_yaml
              v = versions.create(:data => data.to_yaml)
              count_column = versioning_options[:version_count_column].to_s
              if self.attributes.include?(count_column)
                self[count_column] = v.position
              end
            end
          end
    
      end
    end
  end
end